/*
   Copyright (c) 2023 李伟国
   learner-platform is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2. 
   You may obtain a copy of Mulan PSL v2 at:
               http://license.coscl.org.cn/MulanPSL2 
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.  
   See the Mulan PSL v2 for more details. 
*/

package cn.platform.controller;

import cn.platform.constant.ProblemConstant;
import cn.platform.dto.CodeRunMsg;
import cn.platform.dto.CodeRunResult;
import cn.platform.dto.RunnerDto;
import cn.platform.dto.TestInOutDto;
import cn.platform.entity.Problem;
import cn.platform.entity.Runner;
import cn.platform.exception.TestCaseInfoIncompleteException;
import cn.platform.response.ResponseData;
import cn.platform.response.SuccessResponseData;
import cn.platform.service.IProblemService;
import cn.platform.utils.CodeUtils;
import cn.platform.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.Collections;

@RestController
@RequestMapping("/problem")
public class ProblemController extends BaseController {
    @Autowired
    private IProblemService problemService;

    @RequestMapping(value = "/", method = RequestMethod.POST)
    public ResponseData postProblem(@RequestBody Problem problem){
        return new SuccessResponseData(this.problemService.saveRelease(problem));
    }

    //TODO 将题目保存为草稿

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ResponseData getProblemList(@RequestParam(value = "id", required = false)String pid,
                                       @RequestParam(value = "headline", required = false) String headline,
                                       @RequestParam(value = "label", required = false) String label){
        Integer id = null;
        if(!ObjectUtils.isEmpty(pid)){
            id = Integer.valueOf(pid.substring(1));
        }
        return new SuccessResponseData(this.problemService.getProblemByIdAndTitleAndLabels(id, headline, label));
    }

    @RequestMapping(value = "/{id}")
    public ResponseData getProblemById(@PathVariable("id") Integer id){
        return new SuccessResponseData(this.problemService.getById(id));
    }


    @RequestMapping(value = "/test/code", method = RequestMethod.POST)
    public ResponseData postTestCode(@RequestBody CodeRunMsg codeRunMsg){
        if(codeRunMsg == null||
                ObjectUtils.isEmpty(codeRunMsg.getCode())||
                ObjectUtils.isEmpty(codeRunMsg.getLang())){
            throw new TestCaseInfoIncompleteException("测试代码信息不完整");
        }
        return new SuccessResponseData(problemService.saveTestCode(codeRunMsg));
    }

    @RequestMapping(value = "/test/case", method = RequestMethod.POST)
    public ResponseData postTestCase(@RequestBody TestInOutDto testInOutDto){
        if(ObjectUtils.isEmpty(testInOutDto.getProblemId()) || ObjectUtils.isEmpty(testInOutDto.getTestInOuts())){
            throw new TestCaseInfoIncompleteException("测试样例信息不完整");
        }
        Collections.sort(testInOutDto.getTestInOuts());
        problemService.saveTestCase(testInOutDto);
        return SUCCESS_INFO;
    }

    @RequestMapping(value = "/test/sample", method = RequestMethod.POST)
    public ResponseData postTestSample(@RequestBody TestInOutDto testInOutDto){
        if(ObjectUtils.isEmpty(testInOutDto.getProblemId()) || ObjectUtils.isEmpty(testInOutDto.getTestInOuts())){
            throw new TestCaseInfoIncompleteException("测试样例信息不完整");
        }
        Collections.sort(testInOutDto.getTestInOuts());
        problemService.saveTestSample(testInOutDto);
        return SUCCESS_INFO;
    }

    @RequestMapping(value = "/run/test", method = RequestMethod.GET)
    public ResponseData runTestCode(RunnerDto runnerDto){
        Runner runner = new Runner();
        String filePrefix = runnerDto.getFilePrefix() == null ? CodeUtils.filePrefix : runnerDto.getFilePrefix();
        String fileSuffix = runnerDto.getFileSuffix() == null ? CodeUtils.fileSuffix.get(runnerDto.getLang()) : runnerDto.getFileSuffix();
        runner.setProblemIdAndTestType(runnerDto.getProblemId(), ProblemConstant.TEST_TYPE_SAMPLE)
                .setCode(runnerDto.getCode())
                .setLanguage(runnerDto.getLang())
                .setFilePrefix(filePrefix)
                .setFileSuffix(fileSuffix)
                .setDeleteFile(false);
        System.out.println(runner.getRunCmd());
        CodeRunResult codeRunResult = problemService.runTestCode(runner);
        return new SuccessResponseData(codeRunResult);
    }

    /**
     * 运行代码
     * @param runnerDto  代码基本信息
     * @return 运行结果
     */
    @RequestMapping(value="run/code", method = RequestMethod.POST)
    public ResponseData runCode(RunnerDto runnerDto){
        Runner runner = new Runner();
        Long userId = UserUtil.getUserId();
        String filePrefix = runnerDto.getFilePrefix() == null ? CodeUtils.filePrefix : runnerDto.getFilePrefix();
        String fileSuffix = runnerDto.getFileSuffix() == null ? CodeUtils.fileSuffix.get(runnerDto.getLang()) : runnerDto.getFileSuffix();
        runner.setProblemIdAndTestType(runnerDto.getProblemId(), ProblemConstant.TEST_TYPE_CASE)
                .setCode(runnerDto.getCode())
                .setLanguage(runnerDto.getLang())
                .setFilePrefix(filePrefix)
                .setFileSuffix(fileSuffix)
                .setDeleteFile(false);
        System.out.println(runner.getRunCmd());
        CodeRunResult codeRunResult = problemService.runUserCode(userId,runner);
        return new SuccessResponseData(codeRunResult);
    }

}
